from ctypes import *
import sys
import os
from Base import TaskModel, Singleton

class TavResult(Structure):
    _fields_ = [("file_type", c_wchar * 64),
                ("packer_name", c_wchar * 64),
                ("virus_id", c_ulong),
                ("virus_type", c_wchar * 64),
                ("virus_name", c_wchar * 64),
                ]

class TavEngine(Singleton.Singleton):
    def __init__(self):
        
        module_name = os.path.split(os.path.realpath(__file__))[0] + "\\" + os.pardir + "\\Dll\\TavEngine.dll"
        #print module_name
        self.module = cdll.LoadLibrary(module_name)
        self.CreateScaner = self.module.CreateScaner
        self.DestroyScaner = self.module.DestroyScaner
        self.Scaner__Scan = self.module.Scaner__Scan
        self.TavScan = self.module.TavScan
        
        self.Scaner__Scan.argtypes = [c_void_p, c_wchar_p]
        self.TavScan.argtypes = [c_wchar_p]

    def Scan(self, filename):
        result = TavResult()
        self.TavScan(filename, pointer(result))
        return result

class TavScaner():
    def __init__(self):
        self.scaner = TavEngine.Instance().CreateScaner()
    
    def Scan(self, filename):
        result = TavResult()
        TavEngine.Instance().Scaner__Scan(self.scaner, filename, pointer(result))
        return result




class TavScanResult(TaskModel.TaskModel):
    def __init__(self, filename, tav_result):
        self.tav_result = tav_result
        self.filename = filename

   
class TavScanObserver(TaskModel.Observer):
    def OnTavScanComplete(self, filename, tav_result):
        pass


class TavScanTask(TaskModel.Task):
    def __init__(self, filename):
        TaskModel.Task.__init__(self)
        self.filename = filename
    
class TavScanExecutor(TaskModel.Executor):
    def __init__(self):
        self.scaner = TavScaner()
        
    def Exec(self, task):
        filename = task.filename
        tav_result = self.scaner.Scan(filename)
        return TavScanResult(filename, tav_result)


class Tav(TaskModel.TaskModel, Singleton.Singleton):
    def CreateExecutor(self):
        return TavScanExecutor()
    
    def Notify(self, observer, task, result):
            observer.OnTavScanComplete(result.filename, result.tav_result)

    def Scan(self, filename):
        self.PostTask(TavScanTask(filename))
    
    def Scan__(self, filename):
        return self.SendTask(TavScanTask(filename))
    
    def Scans(self, filename_list):
        for filename in filename_list:
            self.Scan(filename)
        
        
        
        

##+--------------------------Test---------------------------+#


class ScanObserver(TavScanObserver):
    def OnTavScanComplete(self, filename, tav_result):
        print filename + "\tScan Result"
        print "file_type\t" + tav_result.file_type
        print "packer_name\t" + tav_result.packer_name
        print "virus_id\t", tav_result.virus_id
        print "virus_type\t" + tav_result.virus_type
        print "virus_name\t" + tav_result.virus_name
        

if __name__ == '__main__':
    
    filename = "V:\\Download\\C53DC46FBAD0C3551CFD27C10D776554"
    result = TavEngine.Instance().Scan(filename)
    print result.virus_name
    
    scaner = TavScaner()
    result = scaner.Scan(filename)
    print result.virus_name
    
    ob = ScanObserver()
    tav = Tav().Instance()
    tav.AddObserver(ob)
    tav.Start()
    tav.Scan(filename)
    
    
        